package com.bsi.oauth;

import com.bsi.exception.Auth2ResponseExceptionTranslator;
import com.bsi.properties.PermitAllConfigProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.security.oauth2.resource.ResourceServerProperties;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint;
import org.springframework.security.web.AuthenticationEntryPoint;

/**
 * @ClassName ResourceServerConfigInit
 * @Author LiuSong
 * @Date 2020/9/2 15:34
 * @Version 1.0
 * @Description 配置Oauth的资源服务器
 */
@Configuration
@EnableResourceServer
@ConditionalOnBean(PermitAllConfigProperties.class)
public class ResourceServerConfig extends ResourceServerConfigurerAdapter {

    @Autowired
    private PermitAllConfigProperties permitAllConfigProperties;

    @Autowired
    private LoadBalancerClient loadBalancerClient;

    @Autowired
    private ResourceServerProperties resource;

    @Override
    public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
        RemoteTokenServices remoteTokenServices = new RemoteTokenServices();
        remoteTokenServices.setLoadBalancerClient(loadBalancerClient);
        remoteTokenServices.setClientId(resource.getClientId());
        remoteTokenServices.setClientSecret(resource.getClientSecret());
        remoteTokenServices.setCheckTokenEndpointUrl(resource.getTokenInfoUri());
        resources.tokenServices(remoteTokenServices);
        // 扩展oauth2对于token过期的异常处理
        AuthenticationEntryPoint authenticationEntryPoint = new OAuth2AuthenticationEntryPoint();
        ((OAuth2AuthenticationEntryPoint) authenticationEntryPoint).setExceptionTranslator(new Auth2ResponseExceptionTranslator());
        resources.authenticationEntryPoint(authenticationEntryPoint);
    }

    @Override
    public void configure(HttpSecurity http) throws Exception {
        http.headers().frameOptions().disable();
        // 允许cors跨域
        http.csrf().disable().cors().and()
                .authorizeRequests()
                .antMatchers(permitAllConfigProperties.getAntPatterns()).permitAll()
                .anyRequest().authenticated();
    }
}
